﻿using System.Data;
using System.Linq;

namespace Model
{
    public static class ContextExtension
    {
        public static void DeleteFxCopReport(this ActualEntities context)
        {
            foreach (var item in context.FxCopIssues)
            {
                context.DeleteObject(item);
            }
            context.SaveChanges();
            foreach (var item in context.Message_FxCopMessage)
            {
                context.DeleteObject(item);
            }
            context.SaveChanges();
            foreach (var item in context.Messages)
            {
                context.DeleteObject(item);
            }
            context.SaveChanges();
        }

        public static void ClearDatabase(this ActualEntities context)
        {
            foreach (var item in context.Assemblies)
            {
                context.DeleteObject(item);
            }
            context.SaveChanges();
            foreach (var item in context.CallGraphEdge_AssemblyDependency)
            {
                context.DeleteObject(item);
            }
            context.SaveChanges();
            foreach (var item in context.CallGraphEdge_MemberDependency)
            {
                context.DeleteObject(item);
            }
            context.SaveChanges();
            foreach (var item in context.CallGraphEdge_ModuleDependency)
            {
                context.DeleteObject(item);
            }
            context.SaveChanges();
            foreach (var item in context.CallGraphEdge_NamespaceDependency)
            {
                context.DeleteObject(item);
            }
            context.SaveChanges();
            foreach (var item in context.CallGraphEdges)
            {
                context.DeleteObject(item);
            }
            context.SaveChanges();
            foreach (var item in context.Categories)
            {
                context.DeleteObject(item);
            }
            context.SaveChanges();
            foreach (var item in context.Category_Subcharacteristic)
            {
                context.DeleteObject(item);
            }
            context.SaveChanges();
            foreach (var item in context.FxCopResolutions)
            {
                context.DeleteObject(item);
            }
            context.SaveChanges();
            foreach (var item in context.Mappings)
            {
                context.DeleteObject(item);
            }
            context.SaveChanges();
            foreach (var item in context.Members)
            {
                context.DeleteObject(item);
            }
            context.SaveChanges();
            foreach (var item in context.Modules)
            {
                context.DeleteObject(item);
            }
            context.SaveChanges();
            foreach (var item in context.Namespaces)
            {
                context.DeleteObject(item);
            }
            context.SaveChanges();
            foreach (var item in context.Projects)
            {
                context.DeleteObject(item);
            }
            context.SaveChanges();
            foreach (var item in context.QualityCharacteristics)
            {
                context.DeleteObject(item);
            }
            context.SaveChanges();
            foreach (var item in context.Rule_FxCopRule)
            {
                context.DeleteObject(item);
            }
            context.SaveChanges();
            context.DeleteFxCopReport();
            foreach (var item in context.Rules)
            {
                context.DeleteObject(item);
            }
            context.SaveChanges();
            foreach (var item in context.Types)
            {
                context.DeleteObject(item);
            }
            context.SaveChanges();
            foreach (var item in context.Effects)
            {
                context.DeleteObject(item);
            }
            context.SaveChanges();
            foreach (var item in context.Answers)
            {
                context.DeleteObject(item);
            }
            context.SaveChanges();
            foreach (var item in context.Questions)
            {
                context.DeleteObject(item);
            }
            context.SaveChanges();
            foreach (var item in context.QualityProfileItems)
            {
                context.DeleteObject(item);
            }
            context.SaveChanges();
        }

        public static void CalculateQualityProfile(this ActualEntities context)
        {
            foreach (var item in context.QualityProfileItems)
            {
                int w = item.Category.Effects.Where(e => e.Answer.IsChecked == true).Sum(e => e.Weight);
                item.Weight = w;
            }
            context.SaveChanges();
        }


        /// <summary>
        /// Gets the proper namespace, let it be a normal namespace, or a pseudo-namespace, that
        /// describes the path of a nested type.
        /// </summary>
        /// <param name="isNested">Value indicating wether the type is nested, or not</param>
        /// <param name="outerType">The nesting type, if any exists, else null</param>
        /// <param name="nonNestedNamespace">The namespace of the nesting type if any exist, or
        /// the namespace of the non-nested type</param>
        /// <param name="createIfNoExists">Determines wether to create a new pseudo-namespace, if
        /// the type is nested, and the namespace is not exist, or not</param>
        /// <returns>The proper namespace</returns>
        /// <exception cref="ObjectNotFoundException">ObjectNotFoundException, if
        /// <paramref name="createIfNoExists">createIfNoExists</paramref> is false, and
        /// pseudo-namespace is not found</exception>
        public static Model.Namespace GetNamespace(this ActualEntities context, bool isNested,
            Model.Type outerType, Model.Namespace nonNestedNamespace, bool createIfNoExists)
        {
            Model.Namespace properNamespace = null;
            if (isNested == true && outerType != null)
            {
                string nestedNSName = outerType.NamespaceName + "." + outerType.Name;
                var nsQuery = context.Namespaces.Where(
                    nestedNS => nestedNS.Name.Equals(nestedNSName));
                if (nsQuery.Count() == 0 && createIfNoExists == true)
                    properNamespace = new Namespace()
                    {
                        Name = nestedNSName
                    };
                else if (nsQuery.Count() == 0 && createIfNoExists == false)
                    throw new ObjectNotFoundException(nestedNSName + " not found!");
                else
                    properNamespace = nsQuery.First();
            }
            else
                properNamespace = nonNestedNamespace;

            return properNamespace;
        }
    }
}